<template>
    <div
        :class="['w-full p-24 box-border', { 'min-loading-height': isLoading }]"
        v-loading="isLoading"
        element-loading-text="加载中....."
    >
        <template v-if="!isLoading">
            <!-- 顶部 -->
            <PageHeader :title="PageType[pageType]" :show-refresh="false">
                <template #custom>
                    <!-- 查看模式 - 只有返回按钮 -->
                    <template v-if="isDisabled">
                        <el-button round type="primary" @click="cancel">返回</el-button>
                    </template>
                    <!-- 新增模式 - 返回、保存草稿、确认发布 -->
                    <template v-if="pageType !== 'see'">
                        <el-button round @click="cancel">取消</el-button>
                        <el-button round type="info" @click="submitForm(ruleFormRef, 'save')">保存草稿</el-button>
                        <el-button round type="primary" @click="submitForm(ruleFormRef, 'release')">确认发布</el-button>
                    </template>
                </template>
            </PageHeader>
            <!-- 表单 -->
            <div class="w-full min-content-header-height card-style common-shadow">
                <el-form
                    class="flex-col"
                    ref="ruleFormRef"
                    :model="ruleForm"
                    :rules="rules"
                    :disabled="isDisabled"
                    label-width="110px"
                    status-icon
                >
                    <!-- 文章标题 -->
                    <el-col :span="12">
                        <el-form-item label="文章标题：" prop="articleTitle">
                            <el-input placeholder="请输入文章标题" v-model="ruleForm.articleTitle"/>
                        </el-form-item>
                    </el-col>
                    <!-- 文章图片列表 -->
                    <el-col :span="16">
                        <el-form-item label="文章图片：" prop="articlePictureList">
                            <el-upload
                                v-model:file-list="ruleForm.articlePictureList"
                                multiple
                                :limit="9"
                                :action="uploadImgURL"
                                :disabled="isDisabled"
                                list-type="picture-card"
                                :on-preview="handlePictureCardPreview"
                            >
                                <Icon name="Plus"/>
                                <template #tip>
                                    <div class="el-upload__tip">注意：最多上传 9 张图片，第一张图片将作为封面使用</div>
                                </template>
                            </el-upload>
                        </el-form-item>
                    </el-col>
                    <!-- 文章图片预览 -->
                    <el-dialog v-model="dialogVisible" top="150px" width="30%">
                        <img class="dialog-image rounded-4 m-12 mt-20" :src="dialogImageUrl" alt="" />
                    </el-dialog>
                    <!-- 文章内容 -->
                    <el-col :span="18">
                        <el-form-item label="文章内容：" prop="articleContent">
                            <RichText v-model="ruleForm.articleContent" :setting="richTextSetting"/>
                        </el-form-item>
                    </el-col>
                </el-form>
            </div>
        </template>
    </div>
</template>

<!--suppress TypeScriptCheckImport -->
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import type { FormInstance, FormRules, UploadProps } from 'element-plus'
import { uploadImgURL } from '@/config'
import { HttpResponse } from '@api/http'
import {
    ArticleDetail,
    ArticleParams,
    httpAddArticle,
    httpArticleDetail,
    httpUpdateArticle
} from '@api/module/brandPromotion'
import {
    ElMessages, FormRule, Storage, timeout
} from '@utils/methods'
import { PageTypeKey } from '@/type/common'

// 组件
import RichText from '@jsdawn/vue3-tinymce'
import PageHeader from '@/components/PageHeader/index.vue'
import Icon from '@/components/Icon/index.vue'
import dayjs from 'dayjs'

// 路由
const { query } = useRoute()
const router = useRouter()

// 页面加载
const isLoading = ref(true)

// 文章 id
const articleId = ref<number>(0)

// 页面标题类型
enum PageType {
    'add' = '新增文章',
    'edit' = '编辑文章',
    'see' = '文章详情'
}

// 是否禁用表单
const isDisabled = computed(() => pageType.value === 'see')

// 是否显示返回按钮
const pageType = ref<PageTypeKey>()

// 表单实例
const ruleFormRef = ref<FormInstance>()

// 表单数据
const ruleForm = reactive<ArticleParams>({
    articleTitle: '',
    articleContent: '',
    releaseStatus: null,
    author: Storage.get('systemInfo').adminName,
    articlePictureList: []
})

// 表单校验
const rules = <FormRules>{
    articleTitle: [
        FormRule.requireRule('请输入文章标题'),
        FormRule.lengthRule(6, 30, '长度在 6-30 个字符')
    ],
    articleContent: [FormRule.requireRule('请输入文章内容')],
    articlePictureList: [FormRule.requireRule('请上传文章图片')]
}

// 文章详情
const articleDetail = ref<ArticleDetail>()

// 获取文章详情 编辑 / 详情
const getArticleDetail = () => {
    httpArticleDetail({
        articleId: articleId.value
    }).then(({ success, data }) => {
        if (success) {
            articleDetail.value = data
            const { articleTitle, articleContent, articlePictureList } = data
            ruleForm.articleTitle = articleTitle
            ruleForm.articleContent = articleContent.replaceAll('\\n', '<br/>')
            ruleForm.articlePictureList = articlePictureList
        }
    }).finally(async () => {
        await timeout(500)
        isLoading.value = false
    })
}

// 页面初始化
const pageInit = async () => {
    pageType.value = <PageTypeKey>query.pageType
    switch (query.pageType) {
    case 'add':
        await timeout(500)
        isLoading.value = false
        break
    default:
        articleId.value = Number(query.articleId)
        await getArticleDetail()
    }
}

pageInit()

// 取消
const cancel = () => {
    router.push({
        path: '/BrandPromotion'
    })
}

// 提交表单参数
type SubmitForm = (formEl: FormInstance | undefined, type: 'save' | 'release') => void

// 提交表单
const submitForm: SubmitForm = async (formEl, type) => {
    if (!formEl) return
    await formEl.validate(valid => {
        if (valid) {
            pageType.value === 'add' ? addArticle(type) : updateArticle(type)
        }
    })
}

// 新增文章
const addArticle = (type: 'save' | 'release') => {
    const {
        articleTitle, articleContent, author, articlePictureList
    } = ruleForm
    // 请求参数
    const params: ArticleParams = {
        articleTitle,
        articleContent,
        author,
        releaseStatus: type === 'save' ? 0 : 1,
        articlePictureList: articlePictureList.map((item: any) => ({
            name: item.name,
            url: item.response.data
        }))
    }
    // 文章添加
    httpAddArticle(params).then(({ success }) => {
        if (success) cancel()
        success ? ElMessages.success('新增成功！') : ElMessages.warning('新增失败！')
    })
}

// 更新文章 保存草稿 | 确认发布
const updateArticle = (type: 'save' | 'release') => {
    const { articleTitle, articleContent, articlePictureList } = ruleForm
    // 更新数据
    const updateParams = {
        ...articleDetail.value,
        articleTitle,
        articleContent,
        createdTime: dayjs(articleDetail.value?.createdTime).format('YYYY-MM-DD HH:mm:ss'),
        releaseStatus: type === 'save' ? 0 : 1,
        articlePictureList: articlePictureList.map((item: any) => ({
            name: item.name,
            url: item.response ? item.response.data : item.url
        }))
    }
    // 文章添加
    httpUpdateArticle(<ArticleDetail>updateParams).then(({ success }) => {
        if (success) cancel()
        success ? ElMessages.success('修改成功！') : ElMessages.warning('修改失败！请重试')
    })
}

// 弹窗状态
const dialogVisible = ref(false)

// 弹窗图路径
const dialogImageUrl = ref('')

// 预览图片
const handlePictureCardPreview: UploadProps['onPreview'] = uploadFile => {
    dialogImageUrl.value = uploadFile.url!
    dialogVisible.value = true
}

// 富文本编辑器设置
const richTextSetting = reactive({
    // 编辑器宽度
    width: 650,
    // 编辑器高度
    height: 460,
    // 占位内容
    placeholder: '请填写文章内容...',
    // 语言包
    language: 'zh-Hans',
    // 语言包地址
    language_url: 'https://www.jsjserve.top/public/files/language/zh.js',
    // 菜单
    menubar: false,
    // 是否可调节大小
    resize: false,
    // eslint-disable-next-line max-len
    // 工具
    toolbar: 'bold italic underline h1 h2 blockquote numlist bullist link image | alignleft aligncenter alignright | removeformat fullscreen',
    // 插件
    plugins: 'codesample link image table lists fullscreen',
    toolbar_mode: 'sliding',
    // 是否只读
    readonly: isDisabled.value,
    // 是否显示 logo
    branding: false,
    // 支持的图片格式
    images_file_types: 'jpeg,jpg,png,gif,bmp,webp',
    forced_root_block: '',
    nonbreaking_force_tab: true,
    link_title: false,
    link_default_target: '_blank',
    content_style: 'body{font-size: 16px}',
    // 开启图片上传模式
    custom_images_upload: true,
    // 图片上传地址
    images_upload_url: uploadImgURL,
    // 图片上传回调
    custom_images_upload_callback: (response: HttpResponse) => response.data
})
</script>

<style lang="less" scoped>
.el-form-item{
    @apply mt-34;
}

.el-form{
    &:first-child{

        .el-form-item {
            @apply mt-20;
        }
    }
}

.dialog-image{
    width: calc(100% - 24px);
}
</style>
